package com.yhy.wxzn.wcs.service.impl;

import cn.hutool.core.util.StrUtil;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yhy.wxzn.wcs.device.plc.task.PlcTaskThread;
import com.yhy.wxzn.wcs.device.rgv.enums.PriorityCodes;
import com.yhy.wxzn.wcs.device.rgv.enums.RgvProgress;
import com.yhy.wxzn.wcs.entity.TaskGenerateRequest;

import com.yhy.wxzn.wcs.entity.WcsFourWayTask;
import com.yhy.wxzn.wcs.entity.WcsMapInfo;
import com.yhy.wxzn.wcs.entity.WcsTask;
import com.yhy.wxzn.wcs.enums.PlcTaskProgress;
import com.yhy.wxzn.wcs.enums.RgvTaskAssignStatus;
import com.yhy.wxzn.wcs.enums.TaskStatus;
import com.yhy.wxzn.wcs.enums.TaskType;
import com.yhy.wxzn.wcs.mapper.WcsTaskMapper;
import com.yhy.wxzn.wcs.service.IWcsTaskService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: wcs_task
 * @Author: jeecg-boot
 * @Date:   2024-01-23
 * @Version: V1.0
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class WcsTaskServiceImpl extends ServiceImpl<WcsTaskMapper, WcsTask> implements IWcsTaskService {


    final WcsTaskMapper wcsTaskMapper;

    final WcsDeviceInfoServiceImpl deviceInfoService;


    @Override
    public WcsTask updatePlcProgress(WcsTask task, String deviceName,Integer plcProgress) {
        int deviceId = StrUtil.isNotEmpty(deviceName) ? deviceInfoService.findByDeviceName(deviceName).getId():plcProgress ;

        UpdateWrapper<WcsTask> wrapper = new UpdateWrapper<>();
        wrapper.lambda().set(WcsTask::getPlcProgress,deviceId).eq(WcsTask::getTaskId,task.getTaskId());
        if (!update(wrapper)) {
            throw new RuntimeException("updatePlcProgress失败");
        }
        log.info("taskId:{},更新plc进度为{}，成功",task.getTaskId(),deviceId);
        return getById(task.getTaskId());
    }

    @Override
    public Result<?> generateTask(TaskGenerateRequest request) {
        Result<?> res;

        switch (TaskType.parseTaskType(request.getTaskType())){
            case CHARGE:
            case IN:
            case OUT:
            case MOVE_LOADED:
            case MOVE_UNLOADED:
            case TRANSFER:
                res = generateRgvTask(request);
                break;
            case MOVE_STATION:
                res = generateStationTask(request);
                break;
            case LIFTER_TASK:
                res = generateLifterTask(request);
                break;
            default:
                res = Result.error("无此任务类型");
        }

        return res;
    }

    private Result<?> generateLifterTask(TaskGenerateRequest request) {
        WcsTask task = new WcsTask();

        task.setTaskType(TaskType.parseTaskType(request.getTaskType()));
        task.setPlcProgress(PlcTaskProgress.WAIT.getTaskProgress());
        task.setStart(request.getStartNodeStr());
        task.setEnd(request.getEndNodeStr());
        task.setTaskStatus(TaskStatus.NEW);
        task.setPriorityCode(PriorityCodes.MANUAL);
        task.setCreateTime(new Date());

        if (save(task)){
            PlcTaskThread.executeTask(task);
            return Result.OK();
        }else {
            return Result.error("生成任务失败");
        }
    }

    private Result<?> generateStationTask(TaskGenerateRequest request) {
        WcsTask task = new WcsTask();

        task.setTaskType(TaskType.parseTaskType(request.getTaskType()));
        task.setPlcProgress(PlcTaskProgress.WAIT.getTaskProgress());
        task.setStart(request.getStartNodeStr());
        task.setEnd(request.getEndNodeStr());
        task.setTaskStatus(TaskStatus.NEW);
        task.setPriorityCode(PriorityCodes.MANUAL);
        task.setCreateTime(new Date());

        if (save(task)){
            PlcTaskThread.executeTask(task);
            return Result.OK();
        }else {
            return Result.error("生成任务失败");
        }
    }

    @NotNull
    private Result<?> generateRgvTask(TaskGenerateRequest request) {
        WcsTask task = new WcsTask();
        task.setAssignStatus(RgvTaskAssignStatus.ASSIGNED);
        task.setProcessRgvDeviceCode(request.getRgvId());
        task.setTaskType(TaskType.parseTaskType(request.getTaskType()));
        task.setStart(request.getStartNodeStr());
        task.setEnd(request.getEndNodeStr());



        if (task.getTaskType() == TaskType.IN || task.getTaskType() == TaskType.OUT)
            task.setPlcProgress(PlcTaskProgress.WAIT.getTaskProgress());
        else
            task.setPlcProgress(PlcTaskProgress.ALL_DEVICE_COMPLETE.getTaskProgress());
        task.setTaskStatus(TaskStatus.NEW);
        task.setRgvProgress(RgvProgress.ASSIGNED_TO_RGV);
        task.setPriorityCode(PriorityCodes.MANUAL);
        task.setCreateTime(new Date());

        if (save(task)){
            return Result.OK();
        }else {
            return Result.error("生成任务失败");
        }
    }



    @Override
    public List<WcsTask> getUnAssignTask() {
        QueryWrapper<WcsTask> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(WcsTask::getAssignStatus,0)
                .in(WcsTask::getTaskType, TaskType.IN,TaskType.OUT,TaskType.TRANSFER,TaskType.CHARGE,TaskType.MOVE_LOADED,TaskType.MOVE_UNLOADED)
                .ne(WcsTask::getTaskStatus, TaskStatus.FINISH.getTaskProgress())
                .ne(WcsTask::getRgvProgress,RgvProgress.RGV_COMPLETE.getTaskProgress());

        return list(wrapper);
    }


    @Override
    public void assignTask(Integer taskNo, Integer id) {
        wcsTaskMapper.assignTask(taskNo,id);
    }

    @Override
    public boolean updateRgvProgressReturnBoole(WcsTask task, RgvProgress rgvProgress) {
        boolean b = wcsTaskMapper.updateRgvProgress(task.getTaskId(), rgvProgress.getTaskProgress());
        if (b){
            log.info("{}号小车更新RGV进度为{}成功",task.getProcessRgvDeviceCode(),rgvProgress);
        }else {
            log.info("{}号小车更新RGV进度为{}失败",task.getProcessRgvDeviceCode(),rgvProgress);
        }
        return b;
    }

    @Override
    public WcsTask updateRgvProgress(WcsTask task, RgvProgress rgvProgress) {
        boolean b = wcsTaskMapper.updateRgvProgress(task.getTaskId(), rgvProgress.getTaskProgress());
        if (b){
            log.info("{}号小车更新RGV进度为{}成功",task.getProcessRgvDeviceCode(),rgvProgress);
        }else {
            log.info("{}号小车更新RGV进度为{}失败",task.getProcessRgvDeviceCode(),rgvProgress);
        }
        return getById(task.getTaskId());
    }


    @Override
    public WcsTask updateTaskStatus(WcsTask task, TaskStatus taskStatus) {
        boolean b = wcsTaskMapper.updateTaskStatus(task.getTaskId(), taskStatus.getTaskProgress());
        if (b){
            log.info("{}号小车更新任务 {} 状态为 {} 成功",task.getProcessRgvDeviceCode(),task.getTaskId(),taskStatus);
        }else {
            log.info("{}号小车更新任务 {} 状态为{}失败",task.getProcessRgvDeviceCode(),task.getTaskId(),taskStatus);
        }
        return getById(task.getTaskId());
    }

    @Override
    public boolean updateTaskStatusReturnBool(WcsTask task, TaskStatus taskStatus) {
        boolean b = wcsTaskMapper.updateTaskStatus(task.getTaskId(), taskStatus.getTaskProgress());
        if (b){
            log.info("{}号小车更新任务 {} 状态为 {} 成功",task.getProcessRgvDeviceCode(),task.getTaskId(),taskStatus);
        }else {
            log.info("{}号小车更新任务 {} 状态为{}失败",task.getProcessRgvDeviceCode(),task.getTaskId(),taskStatus);
        }
        return b;
    }

    @Override
    public WcsTask updateTaskStatusByWmsId(WcsTask task, TaskStatus taskStatus) {
        boolean b = wcsTaskMapper.updateTaskStatusByWmsId(task.getWmsTaskId(), taskStatus.getTaskProgress());
        if (b){
            log.info("{}号小车更新任务wmsId{},状态为{},成功",task.getProcessRgvDeviceCode(),task.getWmsTaskId(),taskStatus);
        }else {
            log.info("{}号小车更新任务wmsId{}状态为{},失败",task.getProcessRgvDeviceCode(),task.getWmsTaskId(),taskStatus);
        }
        return getById(task.getTaskId());
    }

    @Override
    public WcsTask getFirstCanExecuteTask(Integer id) {
        return wcsTaskMapper.getFirstCanExecuteTask(id, TaskStatus.FINISH.getTaskProgress(), TaskStatus.COMMITTED.getTaskProgress(), TaskStatus.CANCEL.getTaskProgress(), TaskStatus.AVOID.getTaskProgress(), RgvProgress.RGV_COMPLETE.getTaskProgress());
    }

    @Override
    public WcsTask queryTaskByWmsId(String wmsTaskId) {
        QueryWrapper<WcsTask> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(WcsTask::getWmsTaskId,wmsTaskId);
        return getOne(wrapper);
    }

    @Override
    public synchronized String insertTask(ArrayList<WcsTask> taskDBs) {

        for (WcsTask task : taskDBs) {
            WcsTask task1 = queryTaskByWmsId(task.getWmsTaskId());
            if (task1 != null) return "存在相同的wmsId"+task.getWmsTaskId();
        }

        if (saveBatch(taskDBs)) {
            return "";
        }else {
            return "保存数据库失败";
        }
    }
}
